#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <string.h>
#include "Process.h"
#include <android/log.h>
#include <malloc.h>
#include "md5c.h"
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

/**
 * 工具方法
 * 返回值 char* 这个代表char数组的首地址
 *  Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串
 */
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
	char* rtn = NULL;
	jclass  clsstring = (*env)->FindClass(env, "java/lang/String");
	jstring strencode = (*env)->NewStringUTF(env, "utf-8");
	jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes","(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,strencode);
	jsize alen = (*env)->GetArrayLength(env, barr);
	jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
	if (alen > 0) {
		rtn = (char*) malloc(alen + 1);
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	(*env)->ReleaseByteArrayElements(env, barr, ba, 0);
	return rtn;
}

/**
 * 检验so库是否运行在书旗项目中，如果在，返回1，否则返回0；
 */
int check(JNIEnv* env) {
	//查找test.Demo类，返回JAVA类的CLASS对象
	jclass cls = (*env)->FindClass(env, "com/shuqi/application/ShuqiApplication");
	if ((*env)->ExceptionCheck(env)) {
		(*env)->ExceptionClear(env);
		return 0;
	}
	if (cls == 0) {
		return 0;
	}

	cls = (*env)->FindClass(env, "com/shuqi/activity/AccountActivity");
	if ((*env)->ExceptionCheck(env)) {
		(*env)->ExceptionClear(env);
		return 0;
	}
	if (cls == 0) {
		return 0;
	}

	// 上层会对下面两个方法混淆，不能这样判断是否运行在书旗小说的app中。目前上面两个就够了
	//获取类中的方法，最后一个参数是方法的签名，通过javap -s -p 文件名可以获得
//	jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getInstance", "()Lcom/shuqi/application/ShuqiApplication;");
//	if ((*env)->ExceptionCheck(env)) {
//		(*env)->ExceptionClear(env);
//		return 0;
//	}
//	if (mid == 0) {
//		return 0;
//	}
//
//	jmethodID midShuqiIsRunning = (*env)->GetStaticMethodID(env, cls, "shuQiIsRunning", "()Z");
//	if ((*env)->ExceptionCheck(env)) {
//		(*env)->ExceptionClear(env);
//		return 0;
//	}
//	if (midShuqiIsRunning == 0) {
//		return 0;
//	}
//
//	jboolean isRunning = (*env)->CallStaticBooleanMethod(env, cls, midShuqiIsRunning);
//	if ((*env)->ExceptionCheck(env)) {
//		(*env)->ExceptionClear(env);
//		return 0;
//	}
//	if (!isRunning) {
//		return 0;
//	}

	return 1;
}

JNIEXPORT jstring JNICALL Java_com_shuqi_application_PasswordProcess_getDbAESEncryKey(JNIEnv* env, jclass clazz)
{
	// 不在书旗项目中运行，返回空字符串
	if (check(env) == 0) {
		return (*env)->NewStringUTF(env, "");
	}

	char *keyString = "UserInfoEncry123";
    return (*env)->NewStringUTF(env, keyString);
}

/*
 * 通过JNI获取登录密码
 * Class:     com_shuqi_application_PasswordProcess
 * Method:    getLgPassword
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_shuqi_application_PasswordProcess_getLgPassword(
		JNIEnv* env, jclass clazz, jstring jInfo) {

	// 不在书旗项目中运行，返回空字符串
	if (check(env) == 0) {
		return (*env)->NewStringUTF(env, "");
	}

	char jstr[50] = "";
    char* begin = "pp-cn-begin";
    char* end = "pp-cn-end";
	char* ps = Jstring2CStr(env, jInfo);

    strcat(jstr,begin);
    strcat(jstr,ps);
    strcat(jstr,end);
    LOGI("ccccc%s", jstr);

	MD5_CTX context = { 0 };
	MD5Init(&context);
	MD5Update(&context, jstr, strlen(jstr));
	unsigned char dest[16] = { 0 };
	MD5Final(dest, &context);

	int i;
	char destination[32] = { 0 };
	for (i = 0; i < 16; i++) {
		sprintf(destination, "%s%02x", destination, dest[i]);
	}
	LOGI("%s", destination);
	return (*env)->NewStringUTF(env, destination);
}

/*
 * 通过JNI获取数据库密码
 * Class:     com_shuqi_application_PasswordProcess
 * Method:    getDbPassword
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_shuqi_application_PasswordProcess_getDbPassword(
		JNIEnv *env, jclass clazz) {

	// 不在书旗项目中运行，返回空字符串
	if (check(env) == 0) {
		return (*env)->NewStringUTF(env, "");
	}

	char* jstr = "shuqi_db_password";

	MD5_CTX context = { 0 };
	MD5Init(&context);
	MD5Update(&context, jstr, strlen(jstr));
	unsigned char dest[16] = { 0 };
	MD5Final(dest, &context);

	int i;
	char destination[32] = { 0 };
	for (i = 0; i < 16; i++) {
		sprintf(destination, "%s%02x", destination, dest[i]);
	}
	LOGI("%s", destination);
	return (*env)->NewStringUTF(env, destination);

}



